.Net Exception Reporter
=======================

The goal of this project is to create a reusable and extensible exception reporter.

* Author:    Joseph Haluska
* CodePlex:  [jah4](http://www.codeplex.com/site/users/view/jah4)
* Started:   9/2/2012
* Version:   0.2.0

Usage
-----

1. Add a reference to NetExceptionReporter.

2. Create an instance of ExceptionReporter and setup automatic catching of uncaught exceptions:

    **Wpf Example**

        // App.xaml.cs

        using System.Diagnostics;
        using System.Windows;
        using System.Windows.Threading;
        using NetExceptionReporter;

        namespace WpfApplicationTest
        {
            /// <summary>
            /// Interaction logic for App.xaml
            /// </summary>
            public partial class App : Application
            {
                static ExceptionReporter _reporter = new ExceptionReporter();
                internal static ExceptionReporter Reporter
                {
                    get { return _reporter; }
                }

                protected override void OnStartup(StartupEventArgs e)
                {
                    #region Catch uncaught exceptions with exception reporter

                    if (!Debugger.IsAttached)
                    {
                        Application.Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler((_s, _e) =>
                        {
                            _e.Handled = true;

                            _reporter.ReportException(_e.Exception);
                        });
                    }

                    #endregion

                    base.OnStartup(e);
                }
            }
        }

    **WindowsForms Example**

        // Program.cs

        using System;
        using System.Diagnostics;
        using System.Threading;
        using System.Windows.Forms;
        using NetExceptionReporter;

        namespace WindowsFormsTest
        {
            static class Program
            {
                static ExceptionReporter _reporter = new ExceptionReporter();
                internal static ExceptionReporter Reporter
                {
                    get { return _reporter; }
                }

                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main()
                {
                    #region Catch uncaught exceptions with exception reporter

                    if (!Debugger.IsAttached)
                    {
                        // Add the event handler for handling UI thread exceptions to the event.
                        Application.ThreadException += new ThreadExceptionEventHandler((s, e) =>
                        {
                            _reporter.ReportException(e.Exception);
                        });

                        // Add the event handler for handling non-UI thread exceptions to the event. 
                        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler((s, e) =>
                        {
                            _reporter.ReportException((Exception)e.ExceptionObject, e.IsTerminating);
                        });

                        // Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
                        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                    }

                    #endregion

                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
            }
        }

3. Manual reporting of an exception:

    **Wpf Example**

        try
        {
            /* code */
        }
        catch (Exception ex)
        {
            App.Reporter.ReportException(ex);
        }

    **WindowsForms Example**

        try
        {
            /* code */
        }
        catch (Exception ex)
        {
            Program.Reporter.ReportException(ex);
        }

4. Customizing the exception reporter:

    The ExceptionReporter constructor can accept an instance of IExceptionWindowBehavior to permit customizing the exception window.

    You can either create a class that implements this interface or extend from class DefaultExceptionWindowBehavior and overload as needed.

    static ExceptionReporter _reporter = new ExceptionReporter(new CustomExceptionWindowBehavior());
    internal static ExceptionReporter Reporter
    {
        get { return _reporter; }
    }

    ...

    [Serializable()]
    public class CustomExceptionWindowBehavior : DefaultExceptionWindowBehavior
    {
        public override string Title
        {
            get
            {
                return "Exception Viewer";
            }
        }

        public override ExceptionWindowStyle Style
        {
            get
            {
                return ExceptionWindowStyle.ShowReportButton;
            }
        }

        public override string OnComposeDetailedDescription(Exception e)
        {
            return "An unexpected error occurred:" + Environment.NewLine +
                    Environment.NewLine +
                    base.OnComposeDetailedDescription(e);
        }

        public override void OnException(Exception e, out bool displayExceptionWindow)
        {
            displayExceptionWindow = true;
        }

        public override void OnReportException(Exception e)
        {
            MessageBox.Show("Report button was pressed.");
        }
    }